import {
    FC, MouseEventHandler,
    useEffect, useRef
} from "react"
import {
    AxesHelper, PerspectiveCamera,
    PointLight, Scene,
    WebGLRenderer, AmbientLight,
    Vector3, Vector2,
    Raycaster, Mesh, BoxGeometry,
    MeshLambertMaterial
} from "three"
import {
    BoxMatrix
} from "R/models";
import State from 'three/examples/jsm/libs/stats.module.js'
import {
    EffectComposer, OrbitControls,
    OutlinePass, RenderPass,
} from "three/examples/jsm/Addons.js";
import { GUI } from "dat.gui";

// 椭圆点位置
const lightPosition = new Vector3(60, 80, 100)

const Page: FC = () => {
    const container = useRef<HTMLCanvasElement>(null),
        scene = new Scene(),
        state = new State(),
        rayCaster = new Raycaster(),
        camera = new PerspectiveCamera()
    const handleClick: MouseEventHandler<HTMLCanvasElement> = (params) => {
        const x = (params.clientX / document.body.clientWidth * 2) - 1, // x坐标均为正向,切换到webgl3d坐标时,因为需要1~-1,所以坐标需要-1
            y = -(params.clientY / document.body.clientHeight * 2) + 1;// y坐标和webgl坐标y轴的方向相反,所以需要转为负数,变为0~-2,所以最后需要+1
        rayCaster.setFromCamera(new Vector2(x, y), camera)


    }
    // 基本对象
    useEffect(() => {
        const bodyele = document.body;
        const renderer = new WebGLRenderer({ canvas: container.current! }),
            pointLight = new PointLight(0xffffff, 10),
            axesHelper = new AxesHelper(100),
            // 后处理效果合成器
            composer = new EffectComposer(renderer)
        camera.fov = 90;
        camera.aspect = bodyele.clientWidth / bodyele.clientHeight;
        camera.near = 1;
        camera.far = 1000;
        camera.updateProjectionMatrix();


        // 后处理通道
        const renderPass = new RenderPass(scene, camera)
        composer.addPass(renderPass)

        // 后处理包装
        const outline = new OutlinePass(
            new Vector2(bodyele.clientWidth, bodyele.clientHeight),
            scene, camera);


        outline.visibleEdgeColor.set(0xffff00);

        composer.addPass(outline)
        renderer.setClearAlpha(.4)
        const gui = new GUI()
        pointLight.position.copy(lightPosition)
        pointLight.decay = 0
        scene.add(
            new AmbientLight(0xffffff, 1),
            axesHelper,
            pointLight,
            BoxMatrix

        )



        camera.position.set(15, 14, 13)
        camera.lookAt(BoxMatrix.position)
        new OrbitControls(camera, renderer.domElement)

        renderer.setSize(bodyele.clientWidth * devicePixelRatio, bodyele.clientHeight * devicePixelRatio)
        bodyele.appendChild(state.dom)
        console.log(camera);
        // 设置渲染每一帧时不清除颜色缓冲区
        renderer.autoClear = false;
        function roun() {
            const obj = rayCaster.intersectObjects<Mesh<BoxGeometry, MeshLambertMaterial>>(scene.children).at(0)
            outline.selectedObjects = obj ? [obj.object] : [];
            state.update()

            // renderer.setViewport(100, 100, bodyele.clientWidth / 2, bodyele.clientHeight / 2)
            // camera.setViewOffset(bodyele.clientWidth, bodyele.clientHeight, 0, bodyele.clientHeight / 2, bodyele.clientWidth / 2, bodyele.clientHeight / 2,)

            renderer.setViewport(0, bodyele.clientHeight / 2, bodyele.clientWidth / 2, bodyele.clientHeight / 2)
            composer.render()
            renderer.setViewport(bodyele.clientWidth / 2, 0, bodyele.clientWidth / 2, bodyele.clientHeight / 2)
            composer.render()
            renderer.setViewport(0, 0, bodyele.clientWidth / 2, bodyele.clientHeight / 2)
            composer.render()
            renderer.setViewport(bodyele.clientWidth / 2, bodyele.clientHeight / 2, bodyele.clientWidth / 2, bodyele.clientHeight / 2)
            composer.render()
            requestAnimationFrame(roun)
        }

        roun()
        return () => {

            gui.destroy()
            // renderer.dispose()
        }
    }, [])
    return <canvas onMouseMove={handleClick} ref={container}></canvas>
}
export default Page